package com.dtec.common.util;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.StringTokenizer;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

public class EncryptionUtil {
	static Key key;
	static KeyGenerator keyGen;
	static Cipher enCipher;
	static Cipher deCipher;

	/**
	 * Encoded the key string with BASE64
	 * 
	 * @return
	 */
	public static String getEncodedKey() {
		return getSdpInviteKey();
	}

	/**
	 * 产生AES Key
	 * 
	 * @return 返回产生的AES key
	 */
	public static Key getKey() {
		return key;
	}

	public static boolean setKeyFromSdpInvite(byte[] b) {
		String str = new String(b);
		System.out.println(str);
		StringTokenizer st = new StringTokenizer(str, "\r\n");
		String result = "";
		while (st.hasMoreTokens()) {
			String t = st.nextToken();
			if (t.contains("k=")) {
				result = t;
				break;
			}
		}
		if (!result.equals("")) {
			setKey(result.substring(result.indexOf(":") + 1));
			return true;
		} else {
			key = null;
		}
		return false;
	}

	/**
	 * 解密时通过Invite 请求获取的key String 还原java.sercurity.Key
	 * 
	 * @param k
	 */
	public static void setKey(String k) {
		byte[] b = null;
		try {
			b = new BASE64Decoder().decodeBuffer(k);
		} catch (IOException e) {
			e.printStackTrace();
		}
		key = b != null ? new SecretKeySpec(b, "AES") : null;
		System.out.println("KEY:" + new String(key.getEncoded()));
	}

	/**
	 * 
	 * @param b
	 *            采集到的byte数据
	 * @return 加密过后的byte数据
	 * @description
	 * 
	 */
	public static byte[] changeBytes(byte[] b, int mode) {
		byte[] r = null;
		try {
			if (key != null) {

				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

				cipher.init(mode, key);

				if (mode == Cipher.ENCRYPT_MODE) {

					int ctLength = 0;

					r = new byte[cipher.getOutputSize(b.length)]; // 密文

					ctLength = cipher.update(b, 0, b.length, r, 0);

					ctLength += cipher.doFinal(r, ctLength);

				} else {

					r = cipher.update(b);

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return r;
	}

	public static byte[] encryptionBytes(byte[] b) {
		return changeBytes(b, Cipher.ENCRYPT_MODE);
	}

	public static byte[] encryption(byte[] b) {
		byte[] r = null;
		try {
			if (key != null) {
				if (enCipher == null) {
					enCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
					enCipher.init(Cipher.ENCRYPT_MODE, key);
				}
				int ctLength = 0;
				r = new byte[enCipher.getOutputSize(b.length)]; // 密文
				ctLength = enCipher.update(b, 0, b.length, r, 0);
				ctLength += enCipher.doFinal(r, ctLength);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return b;
		}
		return r;
	}

	/**
	 * 将比特数据解密，在调用此方法前，需从Invite消息中获取String key
	 * 
	 * @param b
	 *            通话对方发过来的byte数据
	 * 
	 * @return
	 */
	public static byte[] decryptionBytes(byte[] b) {
		return changeBytes(b, Cipher.DECRYPT_MODE);
	}

	public static byte[] decryption(byte[] b) {
		byte[] r = null;
		try {
			if (key != null) {
				if (deCipher == null) {
					deCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
					deCipher.init(Cipher.DECRYPT_MODE, key);
				}
				r = deCipher.update(b);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return b;
		}
		return r;
	}

	/**
	 * 获取Invite 请求所需的Key:k=base64:Key
	 * 
	 * @return 返回经过base64的key
	 */
	public static String getSdpInviteKey() {
		return new sun.misc.BASE64Encoder().encode(key.getEncoded());
	}

	public static void start() {
		if (key == null) {
			try {
				keyGen = KeyGenerator.getInstance("AES");
				keyGen.init(128);
				key = keyGen.generateKey();
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
